package sanshi.contect.udpstarter.client;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import sanshi.contect.udpstarter.entity.UDPEntity;
import sanshi.contect.udpstarter.execption.HostVerifieyException;

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import static sanshi.contect.udpstarter.util.UDPHostUtil.isValidIPAddress;

/**
 * udp 客户端
 */
@Slf4j
@Data
public class UDPClient {

    
    private static final String OVERMARK = "over";
    
    private UDPEntity entity;

    /**
     * 暴露的发送接口
     * @param data 数据
     */
    public void send(byte[] data) {
        DatagramSocket socket = null;
        InetAddress address = null;
        //1.定义服务器的地址、端口号、数据
        try {
            String hosts = entity.getHosts();
            String[] hostArr = hosts.split(",");
            for (String host : hostArr) {
                //格式验证
                if (!isValidIPAddress(host)){
                    throw new HostVerifieyException("==============>配置文件中配置ip格式错误，重新配置<==============");
                }
                address = InetAddress.getByName(host);
                dataSplitSend(data, address);

            }
            log.info("==============>通过udp发送接口时，数据发送成功<================");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null){
                socket.close();
            }
        }
    }

    /**
     * 全部需要发送的数据
     * @param data 本次需要全部发送的数据
     */
    private void dataSplitSend(byte[] data, InetAddress address) throws IOException {

        int sendNum = 1;
        //每次发送的起始 结束位置
        int  startByteIndex, endByteIndex;
        boolean overFlag = false;
        do {
            //切割发送的数据
            startByteIndex= (sendNum - 1) * entity.getByteSize();
            endByteIndex = sendNum * entity.getByteSize();

            //最后一次的数据
            if (endByteIndex > data.length){
                endByteIndex = data.length;
                overFlag = true;
            }

            //每次发送的的数据
            byte[] splitData = Arrays.copyOfRange(data, startByteIndex, endByteIndex);
//            System.out.println("获取的数据为: " + new String(splitData));
            // 正常发送数据
            sendData(splitData, address);

            //用于计算发送的总数
            ++sendNum;

            if (overFlag){
                //发送结束标识
                sendData((OVERMARK).getBytes(StandardCharsets.UTF_8), address);
            }
        }while (data.length > endByteIndex);
    }

    /**
     * 发送数据接口
     * @param data 需要进行发送的数据
     */
    private void sendData(byte[] data, InetAddress address) throws IOException {
        //创建数据报，包含发送的数据信息
        DatagramPacket packet = new DatagramPacket(data, data.length, address, entity.getClientPort());
        //创建DatagramSocket对象
        DatagramSocket socket = new DatagramSocket();
        //向服务器端发送数据报
        socket.send(packet);
    }
}
